package com.joesem.sale.client.base

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.os.Parcelable
import android.util.Log
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.WindowManager
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.Toast
import androidx.annotation.ColorInt
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.viewbinding.ViewBinding
import com.blankj.utilcode.util.BarUtils
import com.blankj.utilcode.util.ConvertUtils
import com.google.android.material.snackbar.Snackbar
import com.jiaxing.sale.client.R
import com.jiaxing.sale.client.databinding.ActivityBaseBinding
import com.jiaxing.sale.client.databinding.LayoutToolbarBinding
import com.joesem.sale.client.MyApplication
import com.joesem.sale.client.widget.dialog.LoadingDialog
import java.lang.reflect.ParameterizedType

abstract class BaseActivity<Bind : ViewBinding> : AppCompatActivity(), UiImpl {
    open lateinit var bind: Bind
    open lateinit var baseBind: ActivityBaseBinding
    private var loading: LoadingDialog? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
            window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
                    View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
            window.navigationBarColor=R.color.bgColor.color()
        }
        super.onCreate(savedInstanceState)
        setStatusColor(Color.TRANSPARENT)
        baseBind = ActivityBaseBinding.inflate(layoutInflater)
        baseBind.baseToolbar.initToolbar(savedInstanceState)
        baseBind.initBind(savedInstanceState)
        setContentView(baseBind.root)

    }

    private fun Activity?.setStatusColor(
        @ColorInt color: Int,
    ) {
        this?.window?.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
        this?.window?.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
        this?.window?.statusBarColor = color
    }

    private fun ActivityBaseBinding.initBind(savedInstanceState: Bundle?) {
        try {
            this@BaseActivity::class.java.genericSuperclass.let { it ->
                val type = ((it as ParameterizedType).actualTypeArguments[0]) as Class<*>
                type.getDeclaredMethod("inflate", LayoutInflater::class.java).let {
                    bind = it.invoke(null, layoutInflater) as Bind
                    baseContent.addView(bind.root)
                    bind.initView(savedInstanceState)
                    bind.initListener()
                }
            }
        } catch (e: Exception) {
        }
    }

    private fun LayoutToolbarBinding.initToolbar(savedInstanceState: Bundle?) {
        BarUtils.getStatusBarHeight().let {
            root.setPadding(
                root.paddingLeft,
                it + 8f.dp(),
                root.paddingRight,
                root.paddingBottom
            )
        }
        toolbarButtonLeft.setOnClickListener {
            onBackPressed()
        }
        toolbar(savedInstanceState)
    }

    private fun hideSoftKeyboard(activity: Activity?) {
        activity?.currentFocus?.let { focus ->
            ContextCompat.getSystemService(focus.context, InputMethodManager::class.java)?.let {
                it.hideSoftInputFromWindow(focus.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
            }
            focus.clearFocus()
        }
    }

    private fun isShouldHideInput(view: View, event: MotionEvent): Boolean {
        if (view is EditText) {
            val leftTop = intArrayOf(0, 0)
            view.getLocationInWindow(leftTop)
            val left = leftTop[0]
            val top = leftTop[1]
            val bottom = top + view.getHeight()
            val right = left + view.getWidth()
            return !(event.x > left && event.x < right && event.y > top && event.y < bottom)
        }
        return false
    }

    protected open fun toolbarTheme() {
        baseBind.baseToolbar.apply {
            toolbarBg.setBackgroundColor(R.color.themeColor.color())
            toolbarButtonLeft.setColorFilter(R.color.white.color())
            toolbarTitle.setTextColor(R.color.white.color())
            toolbarButtonRight.setColorFilter(R.color.white.color())
        }
    }


    override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
        ev?.let {
            if (it.action == MotionEvent.ACTION_DOWN) {
                currentFocus?.let { v ->
                    if (isShouldHideInput(v, ev)) {
                        hideSoftKeyboard(this)
                    }
                }
            }
        }
        return super.dispatchTouchEvent(ev)
    }

    protected open fun LayoutToolbarBinding.toolbar(savedInstanceState: Bundle?) {

    }

    override fun observerIntent(intent: Any?) {
        bind.initIntent(intent)
    }

    override fun showLoading() {
        Log.i("request", "showLoading.... ")
        if (loading == null)
            loading = LoadingDialog(this)
        loading?.show()
    }

    override fun dismissLoading() {
        Log.i("request", "dismissLoading.... ")
        loading?.dismiss()
    }

    protected open fun Bind.initIntent(intent: Any?) {

    }

    protected abstract fun Bind.initView(savedInstanceState: Bundle?)

    protected open fun Bind.initListener() {

    }

    open fun make(msg: String) {
        baseBind.baseContent.toastMake(msg)
    }

}

fun View.toastMake(msg: String) {
    Snackbar.make(this, msg, Snackbar.LENGTH_SHORT).show()
}

fun toast(msg: String?) {
    Toast.makeText(MyApplication.instance, msg.orEmpty(), Toast.LENGTH_SHORT).show()
}

fun <T : ViewBinding> T.visible() {
    this.root.visibility = View.VISIBLE
}

fun <T : ViewBinding> T.gone() {
    this.root.visibility = View.GONE
}

fun <T : ViewBinding> T.invisible() {
    this.root.visibility = View.INVISIBLE
}

fun View.visible() {
    this.visibility = View.VISIBLE
}

fun View.gone() {
    this.visibility = View.GONE
}

fun View.invisible() {
    this.visibility = View.INVISIBLE
}


inline fun <reified Ac : Activity> Context?.launch(vararg value: Pair<String, Any?>) {
    this?.let { it ->
        startActivity(groupValue(Intent(it, Ac::class.java), *value))
    }
}

fun groupValue(intent: Intent, vararg value: Pair<String, Any?>): Intent {
    return intent.apply {
        value.forEach {
            when (val second = it.second) {
                is String -> putExtra(it.first, second)
                is Int -> putExtra(it.first, second)
                is Boolean -> putExtra(it.first, second)
                is Double -> putExtra(it.first, second)
                is Float -> putExtra(it.first, second)
                is Parcelable -> putExtra(it.first, second)
            }
        }
    }
}

inline fun <reified Ac : Activity> Fragment?.launch(vararg value: Pair<String, Any?>) {
    this?.requireContext()?.apply {
        startActivity(groupValue(Intent(this, Ac::class.java), *value))
    }
}

fun Int.color() = MyApplication.instance.resources.getColor(this)

fun Int.strings() = MyApplication.instance.resources.getString(this)

fun Float.dp() = ConvertUtils.dp2px(this)